﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using WLG.Model.Interface;
using WindowsLive.Client.Passport;
using System.Windows.Forms;
using WindowsLive.Writer.Passport;
using WindowsLive.Client;
using System.Collections;
using System.Xml;
using Microsoft.WindowsLive.Id.Client;
using System.Net;
using System.IO;
namespace WLG.AuthenticationProvider
{

    static class NotificationAdapter
    {
        private const string NOTIFY_API_URL = "http://sup.live.com/whatsnew/whatsnewservice.asmx";
        private const string requestXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><soap:Header><WNApplicationHeader xmlns=\"http://www.msn.com/webservices/AddressBook\"><ApplicationId>3B119D87-1D76-4474-91AD-0D7267E86D04</ApplicationId></WNApplicationHeader><WNAuthHeader xmlns=\"http://www.msn.com/webservices/AddressBook\"><TicketToken>{0}</TicketToken></WNAuthHeader></soap:Header><soap:Body><GetContactsRecentActivity xmlns=\"http://www.msn.com/webservices/AddressBook\"><entityHandle><Cid>{1}</Cid></entityHandle><locales><string>en-US</string></locales><count>1</count></GetContactsRecentActivity></soap:Body></soap:Envelope>";

        public static string GetNotifications(Identity oId)
        {
            string result = "";

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(NOTIFY_API_URL);
            string ticket = "";
            string cID = "";

            cID = System.Int64.Parse(oId.cId, System.Globalization.NumberStyles.AllowHexSpecifier).ToString();
            //Get ticket for storage service.
            try
            {
                ticket = oId.GetTicket("http://sup.live.com/whatsnew/whatsnewservice.asmx", "MBI", false);
            }
            catch (WLLogOnException wlex)
            {
                //Check to see if FlowUrl is defined.
                if (wlex.FlowUrl != null)
                {
                    //If FlowUrl is defined, direct user to the web page to correct the error.
                    MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                }
                else
                {
                    //If FlowUrl is not defined, simply display the ErrorString.
                    MessageBox.Show(wlex.ErrorString);
                }
            }

            byte[] postData = new UTF8Encoding(false).GetBytes(String.Format(requestXml, ReplaceInvalidXMLChars(ticket), ReplaceInvalidXMLChars(cID)));

            //request.Headers.Add("Authorization", "WLID1.0 " + ticket);
            request.AllowAutoRedirect = false;
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; OfficeLiveConnector.1.3; OfficeLivePatch.1.3)";
            request.ContentType = "text/xml";
            request.ProtocolVersion = HttpVersion.Version11;
            request.Method = "POST";
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(postData, 0, postData.Length);
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            StreamReader loResponseStream = new
                  StreamReader(response.GetResponseStream());

            result = loResponseStream.ReadToEnd();

            loResponseStream.Close();
            response.Close();
            return result;
        }

        public static string ReplaceInvalidXMLChars(string inString)
        {
            inString = inString.Replace("<", "&lt;");
            inString = inString.Replace(">", "&gt;");
            inString = inString.Replace("\"", "&quot;");
            inString = inString.Replace("'", "&apos;");
            inString = inString.Replace("&", "&amp;");

            return inString;
        }
    }





    public class WindowsLiveAuthenticationProvider : IAuthenticationProvider
    {
        IdentityManager oIDMgr;
        Identity oID;
        private string currentUserName;
        private string defaultUserName;
        System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);


        public WindowsLiveAuthenticationProvider()
        {
            //Try initializing the global instance of IdentityManager.
            try
            {
                oIDMgr = IdentityManager.CreateInstance("Tailspin Toys;user@tailspintoys.com;Tailspin Toys Application", "Windows Live ID Client Sample");
            }
            catch (WLLogOnException wlex)
            {
                //Check to see if FlowUrl is defined.
                if (wlex.FlowUrl != null)
                {
                    //If FlowUrl is defined, direct user to the web page to correct the error.
                    MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                }
                else
                {
                    //If FlowUrl is not defined, simply display the ErrorString.
                    MessageBox.Show(wlex.ErrorString);
                }
            }

            //Check the config file to see if a default user is defined.
            defaultUserName = ConfigurationManager.AppSettings["defaultUserName"];
            if (!String.IsNullOrEmpty(defaultUserName))
            {
                TrySilentSignIn();
            }
            else
            {
                //If no default user is defined, try instantiating the global Identity object instance from scratch.
                try
                {
                    oID = oIDMgr.CreateIdentity();
                }
                catch (WLLogOnException wlex)
                {
                    //Check to see if FlowUrl is defined.
                    if (wlex.FlowUrl != null)
                    {
                        //If FlowUrl is defined, direct user to the web page to correct the error.
                        MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                    }
                    else
                    {
                        //If FlowUrl is not defined, simply display the ErrorString.
                        MessageBox.Show(wlex.ErrorString);
                    }
                }
            }
        }

        private void TrySilentSignIn()
        {
            //Try instantiating the global Identity object instance with the username from the config file.
            try
            {
                oID = oIDMgr.CreateIdentity(defaultUserName);
            }
            catch (WLLogOnException wlex)
            {
                //Check to see if FlowUrl is defined.
                if (wlex.FlowUrl != null)
                {
                    //If FlowUrl is defined, direct user to the web page to correct the error.
                    MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                }
                else
                {
                    //If FlowUrl is not defined, simply display the ErrorString.
                    MessageBox.Show(wlex.ErrorString);
                }
            }

            //Check that the username is valid.
            if (oID != null)
            {
                //Check to make sure the user has stored their username and password.
                if (oID.SavedCredentials == CredentialType.UserNameAndPassword)
                {
                    try
                    {
                        //Try silent authentication.
                        if (oID.Authenticate(AuthenticationType.Silent))
                        {
                            currentUserName = defaultUserName;
                        }
                        else
                        {
                            MessageBox.Show("Default user's stored sign-in name and password are invalid.");
                        }
                    }
                    catch (WLLogOnException wlex)
                    {
                        //Check to see if FlowUrl is defined.
                        if (wlex.FlowUrl != null)
                        {
                            //If FlowUrl is defined, direct user to the web page to correct the error.
                            MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                        }
                        else
                        {
                            //If FlowUrl is not defined, simply display the ErrorString.
                            MessageBox.Show(wlex.ErrorString);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Default user hasn't stored sign-in name and password.");
                }
            }
            else
            {
                MessageBox.Show("defaultUserName in config file has an invalid value.");
                config.AppSettings.Settings.Remove("defaultUserName");
                config.Save(ConfigurationSaveMode.Modified);
                ConfigurationManager.RefreshSection("appSettings");
            }
        }

        public WLG.Model.Permissions.Identity SignIn()
        {
           WLG.Model.Permissions.Identity result = new WLG.Model.Permissions.Identity();


           if (!oID.IsAuthenticated)
           {
               try
               {
                   //Try to authenticate the user by showing the Sign-In dialog window.
                   if (oID.Authenticate())
                   {
                       currentUserName = oID.UserName;
                   }
                   else
                   {
                       MessageBox.Show("Authentication failed");
                   }
               }
               catch (WLLogOnException wlex)
               {
                   //Check to see if FlowUrl is defined.
                   if (wlex.FlowUrl != null)
                   {
                       //If FlowUrl is defined, direct user to the web page to correct the error.
                       MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                   }
                   else
                   {
                       //If FlowUrl is not defined, simply display the ErrorString.
                       MessageBox.Show(wlex.ErrorString);
                   }
               }
           }
           else
           {
               //If user is authenticated, they intended to Sign-Out. Try signing the user out.
               try
               {
                   oID.CloseIdentityHandle();
                   currentUserName = "";
               }
               catch (WLLogOnException wlex)
               {
                   //Check to see if FlowUrl is defined.
                   if (wlex.FlowUrl != null)
                   {
                       //If FlowUrl is defined, direct user to the web page to correct the error.
                       MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                   }
                   else
                   {
                       //If FlowUrl is not defined, simply display the ErrorString.
                       MessageBox.Show(wlex.ErrorString);
                   }
               }
           }


            result.CID = this.oID.cId;
            result.Username = this.oID.UserName;

            result.Ticket.Add(new Uri("http://sup.live.com/whatsnew/whatsnewservice.asmx"), this.oID.GetTicket("http://sup.live.com/whatsnew/whatsnewservice.asmx", "MBI", false));

            return result;
        }


    }
}
